package com.learn.excel.hawkeye.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.learn.excel.core.common.cache.CacheHandler;
import com.learn.excel.core.consts.ErrorCode;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @author anri
 * @date 2020/9/23 11:42
 */
@CrossOrigin
public class BaseController implements Serializable {
    @Resource
    protected HttpServletRequest request;

    @Resource
    protected HttpSession session;

    @Resource
    protected ServletContext application;

    @Resource
    protected CacheHandler cacheHandler;

    private static final long serialVersionUID = -2922643148219775629L;
    public static final String statusNormal = "200";//状态码 成功
    public static final String statusFail = "0";//状态码 失败

    private static final String SYS_STATUS = "status";//状态码
    private static final String SYS_ERROR_CODE = "code";//错误码
    private static final String SYS_ERROR_MSG = "msg";//错误提示语
    private static final String SYS_PAGE_DATA = "data";//结果集

    private static ThreadLocal<Map<String, Object>> currentResult = new ThreadLocal<>();
    private static ThreadLocal<Map<String, Object>> currentParam = new ThreadLocal<>();
    private static ThreadLocal<Object> currentData = new ThreadLocal<>();
    private static ThreadLocal<String> currentStatus = new ThreadLocal<>();
    private static ThreadLocal<String> currentMsg = new ThreadLocal<>();
    private static ThreadLocal<String> currentErrorCode = new ThreadLocal<>();
    private static ThreadLocal<Integer> currentRows = new ThreadLocal<>();

    /**
     * @Description description
     * @MethodName 设置错误码
     */
    public Map<String, Object> setResultCode(String status, String code, String msg, Object data) {
        setStatus(status);
        setErrorCode(code);
        setMsg(msg);
        setDatas(data);
        return setResult();
    }

    /**
     * 返回成功的结果集
     */
    public Map<String, Object> setSuccessResult() {
        return setResultCode(statusNormal, ErrorCode.NORMAL.getErrCode(), ErrorCode.NORMAL.getErrMsg(), null);
    }

    /**
     * 返回成功的结果集
     *
     * @param data 查询结果
     */
    public Map<String, Object> setSuccessResult(Object data) {
        return setResultCode(statusNormal, ErrorCode.NORMAL.getErrCode(), ErrorCode.NORMAL.getErrMsg(), data);
    }

    /**
     * 返回异常
     *
     * @param code 错误码
     * @param msg  错误信息
     */
    public Map<String, Object> setErrorResult(String code, String msg) {
        return setResultCode(statusFail, code, msg, null);
    }

    /**
     * 返回异常
     *
     * @param errcode 错误码
     */
    public Map<String, Object> setErrorResult(ErrorCode errcode) {
        return setResultCode(statusFail, errcode.getErrCode(), errcode.getErrMsg(), null);
    }

    /**
     * @Description 设置返回json格式时的各种状态、参数和数据
     * @MethodName
     */
    public Map<String, Object> setResult() {
        Map<String, Object> result = getResult();
        if (getData() == null) {
            result.put(SYS_PAGE_DATA, Collections.emptyList());
        } else {
            result.put(SYS_PAGE_DATA, getData());
        }
        if (getErrorCode() == null) {
            result.put(SYS_ERROR_CODE, "");
        } else {
            result.put(SYS_ERROR_CODE, getErrorCode());
        }
        if (getMsg() == null) {
            result.put(SYS_ERROR_MSG, "");
        } else {
            result.put(SYS_ERROR_MSG, getMsg());
        }
        return result;
    }

    /**
     * @Description 初始化本地request、response和返回map
     */
    @ModelAttribute
    public void init() {
        currentResult.remove();
        currentErrorCode.remove();
        currentParam.remove();
        currentStatus.remove();
        currentMsg.remove();
        currentData.remove();
        currentRows.remove();
        currentResult.set(new HashMap<>());
        currentErrorCode.set("");
        currentMsg.set("");
    }

    public Map<String, Object> getParams() {
        return currentParam.get();
    }

    private Map<String, Object> getResult() {
        return currentResult.get();
    }

    public Object getData() {
        return currentData.get();
    }

    public void setDatas(Object obj) {
        currentData.remove();
        Object datas = obj == null ? Collections.EMPTY_LIST : obj;
        currentData.set(datas);
    }

    /**
     * 返回 JSON 格式对象
     *
     * @param object 转换对象
     * @return
     */
    protected String toJson(Object object) {
        return JSON.toJSONString(object, SerializerFeature.BrowserCompatible);
    }


    /**
     * 返回 JSON 格式对象
     *
     * @param object 转换对象
     * @param format 序列化特点
     * @return
     */
    protected String toJson(Object object, String format) {
        if (format == null) {
            return toJson(object);
        }
        return JSON.toJSONStringWithDateFormat(object, format, SerializerFeature.WriteDateUseDateFormat);
    }

    /**
     * <p>
     * 获取分页对象
     * </p>
     */
    protected <T> Page<T> getPage(int pageNumber) {
        return getPage(pageNumber, 10);
    }


    /**
     * <p>
     * 获取分页对象
     * </p>
     *
     * @param pageSize 每页显示数量
     * @return
     */
    protected <T> Page<T> getPage(int pageNumber, int pageSize) {
        return new Page<T>(pageNumber, pageSize);
    }

    public void setStatus(String status) {
        currentStatus.set(status);
    }

    public void setErrorCode(String code) {
        currentErrorCode.set(code);
    }

    public void setMsg(String msg) {
        currentMsg.set(msg);
    }

    public Object getDatas() {
        return currentData.get();
    }

    private String getStatus() {
        return currentStatus.get();
    }

    private String getErrorCode() {
        return currentErrorCode.get();
    }

    private String getMsg() {
        return currentMsg.get();
    }

}
